﻿using System;
using Csla;

namespace Agnes
{
    /// <summary>
    /// Model Base
    /// </summary>
    [Serializable]
    public abstract class ModelBase<T> : BusinessBase<T>
        where T : ModelBase<T>
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static T CreateAsChild()
        {
            return DataPortal.CreateChild<T>();
        }

        public static T CreateAsChild(object createParam)
        {
            return DataPortal.CreateChild<T>(createParam);
        }

        public static T FetchAsChild()
        {
            return DataPortal.FetchChild<T>();
        }

        public static T FetchAsChild(object fetchParam)
        {
            return DataPortal.FetchChild<T>(fetchParam);
        }

        protected override void Child_Create()
        {
            Create(null);
            base.Child_Create();
        }

        private void Child_Create(object createParam)
        {
            Create(createParam);
            base.Child_Create();
        }

        private void Create(object createParam)
        {
            if (Creating(createParam))
            {
                DoCreate(createParam);
                Created(createParam);
            }
        }

        protected virtual bool Creating(object createParam)
        {
            return true;
        }

        protected virtual void DoCreate(object createParam)
        {
        }

        protected virtual void Created(object createParam)
        {
        }

        private void Child_Fetch()
        {
            Fetch(null);
        }

        private void Child_Fetch(object fetchParam)
        {
            Fetch(fetchParam);
        }

        private void Fetch(object fetchParam)
        {
            if (Fetching(fetchParam))
            {
                DoFetch(fetchParam);
                Fetched(fetchParam);
            }
        }

        protected virtual bool Fetching(object fetchParam)
        {
            return true;
        }

        protected virtual void DoFetch(object fetchParam)
        {
        }

        protected virtual void Fetched(object fetchParam)
        {
        }

        public override T Save()
        {
            DataPortal.Update(this);
            return this as T;
        }

        protected void Child_Update()
        {
            if (Updating())
            {
                DoUpdate();
                Updated();
            }
        }

        protected virtual bool Updating()
        {
            Save();
            return true;
        }

        protected virtual void DoUpdate()
        {
        }

        protected virtual void Updated()
        {
        }

        protected void Child_Insert()
        {
            if (Inserting())
            {
                DoInsert();
                Inserted();
            }
        }

        protected virtual bool Inserting()
        {
            return true;
        }

        protected virtual void DoInsert()
        {
        }

        protected virtual void Inserted()
        {
        }

        protected void Child_DeleteSelf()
        {
            if (Deleting())
            {
                DoDelete();
                Deleted();
            }
        }

        protected virtual bool Deleting()
        {
            return true;
        }

        protected virtual void DoDelete()
        {
        }

        protected virtual void Deleted()
        {
        }
    }
}
